﻿#include "businessgroup.h"
#include <AppConfig/appconfig.h>
#include "businessnetwork.h"
#include <SyncManager/syncmanager.h>
#include <Debug/DEBUG.hpp>
#include "businessmsghandler.h"
#include "businessviewmodel.h"
#include "businessuser.h"
#include "businesssql.h"
#include "businessviewmodel.h"

BusinessGroup::BusinessGroup() {}

void BusinessGroup::createGroup(QJsonObject &in, QJsonObject &out)
{
    // get groupName
    std::string groupName = in["groupName"].toString().toStdString();

    // apply for create group

    uint64_t selfID = std::stoi(AppConfig::getInstance().runtimeValue("UserID"));

    SyncManager& syncManager = SyncManager::getInstance();

    SyncPoint point = syncManager.generateUniqueSyncPoint();

    BusinessNetWork::getInstance().sendMessageToServer(2, 12, selfID, 0, point,
                                                       (unsigned char *)groupName.c_str(), groupName.size());

    bool ret = syncManager.waitForSyncPoint(point);
    out["Status"] = ret;
}

void BusinessGroup::updateGroupList(std::shared_ptr<Protocol> protocol)
{
    ProtocolConverter converter;
    converter.setProtocolOption(BusinessNetWork::getInstance().getProtocolOption());
    converter.parseData((unsigned char*)protocol->data());

    nlohmann::json groups = BusinessMsgHandler::getJsonOfMessage(protocol);

    groupNameStore.clear();
    groupIDStore.clear();
    for (auto& i : groups) {
        std::string groupName = i["GroupName"];
        uint64_t groupID = i["GroupID"];
        // insert to store
        groupNameStore[groupName] = i;
        groupIDStore[groupID] = i;
    }
    for (auto i : groupNameStore) {
        qDebug() << i.second.dump();
    }
    BusinessViewModel::getInstance().updateGroupList(groups);

}

nlohmann::json& BusinessGroup::getTargetGroup(const std::string &groupName)
{
    if (!groupNameStore.count(groupName)) {
        DEBUG_INFO("groupNameStore can not find target groupName: " + groupName);
    }
    return groupNameStore[groupName];
}

nlohmann::json &BusinessGroup::getTargetGroup(uint64_t groupID)
{
    if (!groupIDStore.count(groupID)) {
        DEBUG_INFO("groupNameStore can not find target groupName: " + std::to_string(groupID));
    }
    return groupIDStore[groupID];
}

void BusinessGroup::applyForRefreshGroupList(QJsonObject &in, QJsonObject &out)
{
    std::string account = AppConfig::getInstance().runtimeValue("Account");

    BusinessNetWork::getInstance().sendMessageToServer(2, 13, 0, 0, 0,
                                                       (unsigned char *)account.c_str(), account.size());
}

void BusinessGroup::applyForJoinAGroup(QJsonObject &in, QJsonObject &out)
{
    // get groupName
    std::string groupName = in["groupName"].toString().toStdString();

    uint64_t userID = std::stoi(AppConfig::getInstance().runtimeValue("UserID"));
    SyncManager& syncManager = SyncManager::getInstance();

    SyncPoint point = syncManager.generateUniqueSyncPoint();

    BusinessNetWork::getInstance().sendMessageToServer(2, 2, userID, 0, point,
                                                       (unsigned char *)groupName.c_str(), groupName.size());

    bool ret = syncManager.waitForSyncPoint(point);
    if (ret) {
        out["Status"] = true;
    } else {
        out["Status"] = false;
    }
}

void BusinessGroup::leaveGroup(QJsonObject &in, QJsonObject &out)
{
    QString QgroupName = in["groupName"].toString();
    std::string groupName = QgroupName.toStdString();
    AppConfig& config = AppConfig::getInstance();

    uint64_t selfID = std::stoi(config.runtimeValue("UserID"));

    BusinessNetWork::getInstance().sendMessageToServer(2, 4, selfID, 0, 0,
                                                       (unsigned char *)groupName.c_str(), groupName.size());
}

void BusinessGroup::replyGroupApply(QJsonObject &in, QJsonObject &out)
{
    std::string userAccount = in["UserAccount"].toString().toStdString();
    std::string groupName = in["GroupName"].toString().toStdString();
    std::string status = in["Status"].toString().toStdString();

    BusinessUser& userManager = BusinessUser::getInstance();
    User& targetUser = userManager.getTargetUser(userAccount);

    uint64_t targetUserID = targetUser["UserID"];
    uint64_t groupID = BusinessGroup::getInstance().getTargetGroup(groupName)["GroupID"];

    int subType = 15;
    if (status == "accept") {
        subType = 14;
    }

    BusinessNetWork::getInstance().sendMessageToServer(2, subType, targetUserID, groupID, 0, nullptr, 0);
}

void BusinessGroup::updateGroupRequestList(std::shared_ptr<Protocol> protocol)
{
    nlohmann::json groups = BusinessMsgHandler::getJsonOfMessage(protocol);

    BusinessViewModel::getInstance().updateGroupRequestList(groups);
}

void BusinessGroup::applyForRefreshGroupRequestList(QJsonObject &in, QJsonObject &out)
{
    std::string account = AppConfig::getInstance().runtimeValue("Account");
    BusinessNetWork::getInstance().sendMessageToServer(2, 16, 0, 0, 0,
                                                       (unsigned char *)account.c_str(), account.size());
}

void BusinessGroup::updateLocalMessage(QJsonObject &in, QJsonObject &out)
{
    uint64_t groupID = in["GroupID"].toInteger();


    auto messages = BusinessSQL::getInstance().queryLatest30GroupMessage(groupID);

    BusinessUser& userManager = BusinessUser::getInstance();
    for (auto&i : messages) {
        uint64_t senderID = i["SenderID"];
        User& sender = userManager.getTargetUser(senderID);

        BusinessViewModel::getInstance().addMessageFromGroup(sender, groupID, i["Message"], i["MessageType"], i["Time"]);
    }

}
